home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
gamesrc
/
rtanksrc
/
newterp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-07
|
17KB
|
628 lines
#include <stdio.h>
#include <stdlib.h>
#include <dtypes.h>
#include <string.h>
#include <bios.h>
#include <conio.h>
#include "code.h"
#include "host.h"
#include "newload.h"
#include "callasm.h"
#include "newterp.h"
#include "tconfig.h"
#include "tiles.h"
#define BASERANGE 40
extern PLAYER players[10];
extern p_TANK point[10];
extern BOOL update_scr;
extern int num_players;
extern int setbullet;
BOOL usedhit;
/*<f>----------------------------------------
* FUNCTION: <s> void init_interpreter(p_TANK t)
* PURPOSE : Initilize parts of T structure used by interpreter
* :
* CREATION: 01/09/1989 07:16:16
*/
void init_interpreter(p_TANK t)
{
memset(t->var,0,sizeof(t->var));
t->cline=t->prog;
t->depth=0;
t->bwait=0;
t->boom=FALSE;
t->jiggle=FALSE;
t->hit=FALSE;
t->nhits=0;
t->cweapon=0;
t->nomove=FALSE;
t->channel=0;
t->automove = FALSE;
t->autolock = FALSE;
t->jammer = FALSE;
t->blockage = 0;
clear_channel(&t->station);
} /* void init_interpreter(p_TANK t) */
/*<f>----------------------------------------
* FUNCTION: <s> void interprete(p_TANK t, p_PLAYER p)
* PURPOSE : Main interpreter function
* :
* CREATION: 01/09/1989 07:19:42
*/
void interprete(p_TANK t, p_PLAYER p)
{
p_LINE cl;
BOOL next;
int rx1, rx2, rx3;
if (!p->active) return;
cl=t->cline;
if (cl==(0L)) {
p->active=FALSE;
t->died=biostime(0,0);
}
/*
gotoxy(1,1); explain_line(cl);
*/
next=TRUE; usedhit=FALSE;
restore_under_tank(t);
t->var[CWHEREX] =t->px;
t->var[CWHEREY] =t->py;
t->var[CCGDIR] =t->cgpoint;
t->var[CCTDIR] =t->cpoint;
t->var[CHIT] =t->hit;
t->var[CNOMOVE] =t->nomove;
t->var[CBLOCKAGE]=t->blockage;
t->var[CMESSAGE] =any_messages(&t->station);
if (t->automove) {
move_tank(t);
update_scr=TRUE;
}
switch(cl->command) {
case BAD : gotoxy(15,23);
printf("BAD command line encountered");
break;
case _JLT : if (get_arg(t,&cl->arg1) < get_arg(t,&cl->arg2)) {
next=FALSE;
t->cline=get_line_arg(&cl->arg3);
}
break;
case _JGT : if (get_arg(t,&cl->arg1) > get_arg(t,&cl->arg2)) {
next=FALSE;
t->cline=get_line_arg(&cl->arg3);
}
break;
case _GOTO : t->cline=get_line_arg(&cl->arg1);
next=FALSE;
break;
case _JEQ : if (get_arg(t,&cl->arg1) == get_arg(t,&cl->arg2)) {
next=FALSE;
t->cline=get_line_arg(&cl->arg3);
}
break;
case _JNEQ : if (get_arg(t,&cl->arg1) != get_arg(t,&cl->arg2)) {
next=FALSE;
t->cline=get_line_arg(&cl->arg3);
}
break;
case _CALL : do_call(t,&cl->arg1);
next=FALSE;
break;
case _MOVE : if (!t->automove) {
move_tank(t);
update_scr=TRUE;
}
break;
case _LEFT : turn_tank_left(t);
break;
case _GLEFT : turn_gun_left(t);
break;
case _RIGHT : turn_tank_right(t);
break;
case _GRIGHT : turn_gun_right(t);
break;
case _FIRE : shoot(t);
break;
case _RETURN : do_return(t);
break;
case _SET : store(t,&cl->arg1,get_arg(t,&cl->arg2));
break;
case _ADD : store(t,&cl->arg1,
get_arg(t,&cl->arg1)+get_arg(t,&cl->arg2));
break;
case _RAND : store(t,&cl->arg1,1+(rand() % get_arg(t,&cl->arg2)));
break;
case _SELECT : t->cweapon=get_arg(t,&cl->arg1)-1;
break;
case _CHANNEL: t->channel =get_arg(t,&cl->arg1);
t->var[CCHANNEL] = t->channel;
break;
case _AUTO : t->automove=get_arg(t,&cl->arg1);
break;
case _LOCK : t->autolock=get_arg(t,&cl->arg1);
break;
case _JAMMER : t->jammer=get_arg(t,&cl->arg1);
break;
case _TX : transmit(t, get_arg(t,&cl->arg1),
get_arg(t,&cl->arg2),
get_arg(t,&cl->arg3)
);
break;
case _RX : read_message(&t->station, &rx1, &rx2, &rx3);
store(t,&cl->arg1,rx1);
store(t,&cl->arg2,rx2);
store(t,&cl->arg3,rx3);
break;
case _FACE : rx1=best_turn(t->cpoint,get_arg(t,&cl->arg1));
if (rx1==1)
turn_tank_left(t);
else if (rx1==2)
turn_tank_right(t);
break;
case _AIM : rx1=best_turn(t->cgpoint,get_arg(t,&cl->arg1));
if (rx1==1)
turn_gun_left(t);
else if (rx1==2)
turn_gun_right(t);
break;
case _CONV : store(t,&cl->arg3,do_conv(t,get_arg(t,&cl->arg1),get_arg(t,&cl->arg2)));
break;
case _RADAR : if (p->extrasType[RADAR]>0)
store(t, &cl->arg1, check_radar(t) );
break;
case _SCOPE : if (p->extrasType[WBSCAN]>0)
store(t, &cl->arg1, check_scope(t));
break;
case _SCAN : if (p->extrasType[SCANNER]>0)
store(t, &cl->arg1,check_scan(t,get_arg(t,&cl->arg2)));
break;
}
if (usedhit)
t->hit=FALSE;
if (next)
t->cline=t->cline->nextline;
display_tank(t);
} /* void interprete(p_TANK t, p_PLAYER p) */
/*-------------------------------------
* Function : int best_turn(int curr, int dest)
* Purpose : Calculate which is the best direction to turn to face dest
* Date : 02/15/1989 22:05:17
*/
int best_turn(int curr, int dest)
{
int turn, num1, num2;
if (curr==dest)
turn=0;
else {
if (curr > dest) {
num1 = curr-dest;
num2 = 8+dest-curr;
} else {
num1 = 8+curr-dest;
num2 = dest-curr;
}
if (num1 < num2)
turn = 1; /* Move Left, counter-clockwise */
else if (num1 > num2)
turn = 2; /* Move right */
else turn = random(2)+1; /* same dist, any way! */
}
return turn;
} /* int best_turn(int curr, int dest) */
/*-------------------------------------
* Function : void turn_tank_left(p_TANK t)
* Purpose : Turn tank counter-clockwise and update registers
* Date : 02/15/1989 21:55:11
*/
void turn_tank_left(p_TANK t)
{
spin(&t->cpoint,-1);
if (t->autolock)
turn_gun_left(t);
} /* void turn_tank_left(p_TANK t) */
/*-------------------------------------
* Function : void turn_tank_right(p_TANK t)
* Purpose : Turn tank in clockwise direction
* Date : 02/15/1989 21:55:57
*/
void turn_tank_right(p_TANK t)
{
spin(&t->cpoint,1);
if (t->autolock)
turn_gun_right(t);
} /* void turn_tank_right(p_TANK t) */
/*-------------------------------------
* Function : void turn_gun_left(p_TANK t)
* Purpose : Turn tank's gun in counter-clockwise direction
* Date : 02/15/1989 21:56:21
*/
void turn_gun_left(p_TANK t)
{
spin(&t->cgpoint,-1);
update_scr=TRUE;
} /* void turn_gun_left(p_TANK t) */
/*-------------------------------------
* Function : void turn_gun_right(p_TANK t)
* Purpose : Turn tanks gun in clockwise direction
* Date : 02/15/1989 21:56:50
*/
void turn_gun_right(p_TANK t)
{
spin(&t->cgpoint,1);
update_scr=TRUE;
} /* void turn_gun_right(p_TANK t) */
/*-------------------------------------
* Function : void transmit(p_TANK t, int tx1, int tx2, int tx3)
* Purpose : Transmit tx1,2,&3 to any active listening tanks
* Date : 02/13/1989 23:19:34
*/
void transmit(p_TANK t, int tx1, int tx2, int tx3)
{
int a;
for (a=0; a<num_players; a++)
if (players[a].active && t!=point[a] && point[a]->channel==t->channel)
add_message_to_channel(&point[a]->station, tx1, tx2, tx3);
} /* void transmit(p_TANK t, int tx1, int tx2, int tx3) */
/*<f>----------------------------------------
* FUNCTION: <s> void store(p_TANK t, p_ARG a, int n)
* PURPOSE : Store value N into argument A of tank T
* :
* CREATION: 01/09/1989 07:28:27
*/
void store(p_TANK t, p_ARG a, int n)
{
if (a->atype!=SYMBOL) {
gotoxy(15,23);
printf("Attempt to assign to constant");
} else
t->var[a->value]=n;
} /* void store(p_TANK t, p_ARG a, int n) */
/*<f>----------------------------------------
* FUNCTION: <s> int get_arg(p_TANK t, p_ARG a)
* PURPOSE : Get the contents of value pointed to by argument A
* :
* CREATION: 01/09/1989 07:31:18
*/
int get_arg(p_TANK t, p_ARG a)
{
int ret;
ret=0;
if (a->atype==SYMBOL) {
ret=t->var[a->value];
if (a->value==CHIT)
usedhit=TRUE;
} else if (a->atype==CONSTANT)
ret=a->value;
else {
gotoxy(15,23);
printf("Attempt to return line_ref in integer");
}
return ret;
} /* int get_arg(p_TANK t, p_ARG a) */
/*<f>----------------------------------------
* FUNCTION: <s> void spin(int *v, int dir)
* PURPOSE : Spin a tank or gun clockwise or counter-clockwise
* :
* CREATION: 01/09/1989 07:44:59
*/
void spin(int *v, int dir)
{
(*v)+=dir;
if (*v==0) *v=8;
if (*v==9) *v=1;
} /* void spin(int *v, int dir) */
/*<f>----------------------------------------
* FUNCTION: <s> p_LINE get_line_arg(p_ARG a)
* PURPOSE : Return pointer to next line in arg A
* :
* CREATION: 01/09/1989 07:51:05
*/
p_LINE get_line_arg(p_ARG a)
{
p_LINE ret;
ret=0L;
if (a->atype!=LINEREF) {
gotoxy(15,23);
printf("Returning lineref of a non-lineref argument");
} else ret=a->linedest;
return (ret);
} /* p_LINE get_line_arg(p_ARG a) */
/*<f>----------------------------------------
* FUNCTION: <s> void do_call(p_TANK pb, p_ARG pa)
* PURPOSE : Call subroutine at PA
* :
* CREATION: 11/29/1988 14:21:52
*/
void do_call(p_TANK pb, p_ARG pa)
{
if (pb->depth>19) {
gotoxy(15,23);
printf("Too many CALL's");
return;
}
pb->gosub[pb->depth++]=pb->cline;
pb->cline=get_line_arg(pa);
} /* void do_call(p_TANK pb, p_ARG pa) */
/*<f>----------------------------------------
* FUNCTION: <s> void do_return(p_TANK pb)
* PURPOSE : Do a return
* :
* CREATION: 11/29/1988 14:23:35
*/
void do_return(p_TANK pb)
{
if (pb->depth<1) {
gotoxy(15,23);
printf("RETURN without CALL");
return;
}
pb->cline=pb->gosub[--pb->depth];
} /* void do_return(p_TANK pb) */
/*<f>----------------------------------------
* FUNCTION: <s> void shoot(p_TANK p)
* PURPOSE : Fire a bullet in current direction
* :
* CREATION: 12/05/1988 19:16:09
*/
void shoot(p_TANK p)
{
switch (p->cweapon) {
case ROCKET : setbullet = ROCKET1 + p->cpoint-1;
break;
case MACH16 : setbullet = BMACH16;
break;
case LASER : setbullet = LASER15 + ((p->cpoint-1)%4);
break;
case CANNON : setbullet = CANNONBL;
break;
default : setbullet = BMACH8;
break;
}
switch (p->cgpoint) {
case 1 : init_bullet(p->px,p->py,0,-1,BASERANGE);
break;
case 2 : init_bullet(p->px+1,p->py,1,-1,BASERANGE);
break;
case 3 : init_bullet(p->px+1,p->py,1,0,BASERANGE);
break;
case 4 : init_bullet(p->px+1,p->py+1,1,1,BASERANGE);
break;
case 5 : init_bullet(p->px,p->py+1,0,1,BASERANGE);
break;
case 6 : init_bullet(p->px,p->py+1,-1,1,BASERANGE);
break;
case 7 : init_bullet(p->px,p->py,-1,0,BASERANGE);
break;
case 8 : init_bullet(p->px,p->py,-1,-1,BASERANGE);
break;
}
} /* void v_shoot(p_TANK p) */
/*<f>----------------------------------------
* FUNCTION: <s> int check_radar(p_TANK p)
* PURPOSE : Look around for close tanks
* : and return distance
* CREATION: 12/06/1988 11:49:48
*/
int check_radar(p_TANK p)
{
unsigned int f,d,a;
int x,y;
p->var[CTEAM]=ALLOUT;
for (f=40, a=0; a<num_players; a++)
if (players[a].active && p!=point[a] && (point[a]->team!=p->team || p->team==ALLOUT)) {
x=abs(point[a]->px - p->px);
y=abs(point[a]->py - p->py);
d=(x<y) ? y : x;
if (d<f) {
p->var[CTEAM]=point[a]->team;
f=d;
}
}
return ((f==40) ? 0 : f);
} /* int check_radar(p_TANK p) */
/*<f>----------------------------------------
* FUNCTION: <s> int check_scope(p_TANK p)
* PURPOSE : Return the direction to the closest tank
* :
* CREATION: 01/13/1989 12:55:52
*/
int check_scope(p_TANK p)
{
int f,d,a,t;
int x,y;
for (t=-1, f=999, a=0; a<num_players; a++)
if (players[a].active && p!=point[a] && (point[a]->team!=p->team || p->team==ALLOUT)) {
x=abs(point[a]->px - p->px);
y=abs(point[a]->py - p->py);
d=(x<y) ? y : x;
if (d<f) {
p->var[CTEAM]=point[a]->team;
f=d; t=a;
}
}
if (f==999) {
p->var[CTEAM]=ALLOUT;
f=0;
} else {
x=point[t]->px - p->px;
y=point[t]->py - p->py;
if (x==0) {
if (y<0) f=1; else f=5;
} else if (y==0) {
if (x<0) f=7; else f=3;
} else if (x<0) {
if (y<0) f=8; else f=6;
} else {
if (y<0) f=2; else f=4;
}
}
return f;
} /* int check_scope(p_TANK p) */
/*<f>----------------------------------------
* FUNCTION: <s> int do_conv(p_TANK p, int x, int y)
* PURPOSE : Return the direction to the closest tank
* :
* CREATION: 01/13/1989 12:55:52
*/
int do_conv(p_TANK p, int x, int y)
{
int f,xx,yy;
f =0;
xx=x - p->px;
yy=y - p->py;
if (xx==0) {
if (yy<0) f=1; else f=5;
} else if (yy==0) {
if (xx<0) f=7; else f=3;
} else if (xx<0) {
if (yy<0) f=8; else f=6;
} else {
if (yy<0) f=2; else f=4;
}
return f;
}
/* int do_conv(p_TANK p, int x, int y) */
/*<f>----------------------------------------
* FUNCTION: <s> int check_scan(p_TANK p, int n)
* PURPOSE : Perform a scan for robot p in direction n
* :
* CREATION: 12/06/1988 14:02:03
*/
int check_scan(p_TANK p, int n)
{
int dx,dy,a,adx, ady;
BOOL fuzzy;
for (a=0; a<num_players; a++)
if (players[a].active && p!=point[a] && (point[a]->team!=p->team || p->team==ALLOUT)) {
dx=p->px-point[a]->px;
dy=p->py-point[a]->py;
adx=abs(dx);
ady=abs(dy);
if (abs(adx-ady)<2) fuzzy=TRUE; else fuzzy=FALSE;
p->var[CTEAM]=point[a]->team;
switch (n) {
case 1 : if ((adx<2) && (dy> 0)) return TRUE;
break;
case 2 : if ((dx< 0) && (dy> 0) && fuzzy) return TRUE;
break;
case 3 : if ((dx< 0) && (ady<2)) return TRUE;
break;
case 4 : if ((dx< 0) && (dy< 0) && fuzzy) return TRUE;
break;
case 5 : if ((adx<2) && (dy< 0)) return TRUE;
break;
case 6 : if ((dx> 0) && (dy< 0) && fuzzy) return TRUE;
break;
case 7 : if ((dx> 0) && (ady<2)) return TRUE;
break;
case 8 : if ((dx> 0) && (dy> 0) && fuzzy) return TRUE;
break;
}
}
p->var[CTEAM]=ALLOUT;
return FALSE;
} /* int check_scan(p_TANK p, int n) */